package com.terrier.ui.controls
{
    import com.terrier.ui.core.WxVerticalAlign;
    import com.terrier.ui.skins.IWxLabelButtonSkin;
    import com.terrier.ui.skins.WxSkinManager;
    import com.terrier.ui.skins.WxTextStyle;

    import flash.text.TextField;
    import flash.text.TextFieldAutoSize;

    /**
     * 文本标签按钮
     * @author Jarvis.weng
     */
    public class WxLabelButton extends WxButton
    {
        /**
         * @private
         */
        protected var _textDisplay:TextField;

        /**
         * @private
         */
        protected var _maxTextWidth:Number;

        /**
         * @private
         */
        protected var _minTextWidth:Number;

        /**
         * @private
         */
        protected var _maxTextHeight:Number;

        /**
         * @private
         */
        protected var _minTextHeight:Number;

        /**
         * @private
         */
        protected var _autoSize:Boolean;

        /**
         * @private
         */
        protected var _verticalAlign:String = WxVerticalAlign.MIDDLE;

        /**
         * 构造函数
         */
        public function WxLabelButton()
        {
            super();
        }

        /**
         * @private
         */
        override protected function initialize():void
        {
            super.initialize();

            _textDisplay = new TextField();
            _textDisplay.multiline = true;
            _textDisplay.mouseEnabled = false;
            addChild(_textDisplay);

            invalidateView();
            invalidateLayout();
        }

        /**
         * @private
         */
        override public function setSkinID(skinID:String):void
        {
            setSkin(WxSkinManager.getLabelButtonSkin(skinID));
        }

        /**
         * @private
         */
        override public function set data(value:Object):void
        {
            super.data = value;
            if (data == null)
            {
                label = "";
            }
            else
            {
                label = data.hasOwnProperty("label") ? data.label : data as String;
            }
        }

        /**
         * 按钮标签的文本
         * @return
         */
        public function get label():String
        {
            return _textDisplay.text;
        }

        /**
         * @private
         */
        public function set label(value:String):void
        {
            _textDisplay.text = value;

            invalidateView();
            invalidateLayout();
        }

        /**
         * 文本标签的垂直布局方式.
         * @see WxVerticalAlign
         */
        public function get verticalAlign():String
        {
            return _verticalAlign;
        }

        /**
         * @private
         */
        public function set verticalAlign(value:String):void
        {
            _verticalAlign = value;

            invalidateLayout();
        }

        /**
         * 指定按钮是否根据文本的长度来自动调整大小. 如果按钮自动调整大小,则为true; 否则,为false.
         * @default false
         * @return
         */
        public function get autoSize():Boolean
        {
            return _autoSize;
        }

        /**
         * @private
         */
        public function set autoSize(value:Boolean):void
        {
            _autoSize = value;
            setAutoSize(value);

            invalidateLayout();
        }

        /**
         * 当<code>autoSize</code>属性被设为<code>true</code>时, 文本标签的最大宽度. 文本标签的内容超出这个宽度时, 将自动换行.
         * 如果设置的值小于minTextWidth, 则组件会自动修正该值,使之等于minTextWidth.
         * @see #autoSize
         * @return
         */
        public function get maxTextWidth():Number
        {
            return _maxTextWidth;
        }

        /**
         * @private
         */
        public function set maxTextWidth(value:Number):void
        {
            _maxTextWidth = isNaN(minTextWidth) ? value : Math.max(value, minTextWidth);

            invalidateLayout();
        }

        /**
         * 当<code>autoSize</code>属性被设为<code>true</code>时, 文本标签的最小宽度.
         * 如果设置的值大于maxTextWidth, 则组件会自动修正该值,使之等于maxTextWidth.
         * @see #autoSize
         * @return
         */
        public function get minTextWidth():Number
        {
            return _minTextWidth;
        }

        /**
         * @param value
         */
        public function set minTextWidth(value:Number):void
        {
            _minTextWidth = isNaN(maxTextWidth) ? value : Math.min(value, maxTextWidth);

            invalidateLayout();
        }

        /**
         * 文本标签的最大高度. 仅当autoSize属性被设为true时生效
         * 对这个属性赋值时, 组件会确保 maxTextHeight大于或者等于minTextHeight.
         * @see #autoSize
         * @return
         */
        public function get maxTextHeight():Number
        {
            return _maxTextHeight;
        }

        /**
         * @private
         */
        public function set maxTextHeight(value:Number):void
        {
            _maxTextHeight = isNaN(minTextHeight) ? value : Math.max(value, minTextHeight);

            invalidateLayout();
        }

        /**
         * 文本标签的最小高度. 仅当autoSize属性被设为true时生效.
         * 对这个属性赋值时, 组件会确保 minTextHeight 小于或者等于 maxTextHeight.
         * @see #autoSize
         * @return
         */
        public function get minTextHeight():Number
        {
            return _minTextHeight;
        }

        /**
         * @private
         */
        public function set minTextHeight(value:Number):void
        {
            _minTextHeight = isNaN(maxTextHeight) ? value : Math.min(value, maxTextHeight);

            invalidateLayout();
        }

        /**
         * @private
         */
        protected function setAutoSize(value:Boolean):void
        {
            _textDisplay.autoSize = value ? TextFieldAutoSize.LEFT : TextFieldAutoSize.NONE;
        }

        /**
         * 设置文本的大小
         * @private
         */
        protected function measureText(minW:Number, maxW:Number, minH:Number, maxH:Number):void
        {
            setAutoSize(autoSize);

            if (!isNaN(maxW))
            {
                _textDisplay.wordWrap = false;
                if (_textDisplay.width > maxW)
                {
                    _textDisplay.width = maxW;
                    _textDisplay.wordWrap = true;
                }
            }

            if (!isNaN(minW) && _textDisplay.width < minW)
            {
                _textDisplay.width = minW;
                setAutoSize(false);
            }

            if (!isNaN(maxH))
            {
                if (_textDisplay.height > maxH)
                {
                    setAutoSize(false);
                    _textDisplay.height = maxH;
                }
            }

            if (!isNaN(minH))
            {
                if (_textDisplay.height < minH)
                {
                    setAutoSize(false);
                    _textDisplay.height = minH;
                }
            }
        }

        /**
         * @private
         */
        override public function set width(value:Number):void
        {
            autoSize = false;
            super.width = value;
        }

        /**
         * @private
         */
        override public function set height(value:Number):void
        {
            autoSize = false;
            super.height = value;
        }

        /**
         * 文本标签的TextField对象. 方便使用者对文本标签做直接的操作.
         * @return
         */
        public function get textField():TextField
        {
            return _textDisplay;
        }

        /**
         * @private
         */
        override protected function updateLayout():void
        {
            if (_skin == null || !skin.customLayout)
            {
                var leftPad:Number = skin != null ? skin.leftPad : 0;
                var rightPad:Number = skin != null ? skin.rightPad : 0;
                var topPad:Number = skin != null ? skin.topPad : 0;
                var bottomPad:Number = skin != null ? skin.bottomPad : 0;

                _textDisplay.x = leftPad;
                _textDisplay.y = topPad;

                if (autoSize)
                {
                    measureText(minTextWidth, maxTextWidth, NaN, NaN);

                    _width = _textDisplay.width + leftPad + rightPad;
                    _height = _textDisplay.height + topPad + bottomPad;
                }
                else
                {
                    _textDisplay.width = _width - leftPad - rightPad;
                    _textDisplay.height = _textDisplay.textHeight;

                    if (_verticalAlign == WxVerticalAlign.MIDDLE)
                    {
                        _textDisplay.y = topPad + (_height - topPad - bottomPad - _textDisplay.height) / 2;
                    }
                    else if (_verticalAlign == WxVerticalAlign.BOTTOM)
                    {
                        _textDisplay.y = _height - bottomPad - _textDisplay.height;
                    }
                }
            }

            super.updateLayout();

            var txtStyle:WxTextStyle = getTxtStyleByPhase(_phase);

            if (txtStyle != null)
            {
                txtStyle.applyLayout(_textDisplay);
            }
        }

        /**
         * @private
         */
        override protected function updateView():void
        {
            super.updateView();

            if (_skin == null)
            {
                return;
            }

            var txtStyle:WxTextStyle = getTxtStyleByPhase(_phase);

            if (txtStyle != null)
            {
                txtStyle.applyStyle(_textDisplay);
            }
        }

        /**
         * @private
         */
        protected function getTxtStyleByPhase(phase:String):WxTextStyle
        {
            if (skin == null)
            {
                return null;
            }

            var txtStyle:WxTextStyle;

            switch (phase)
            {
                case WxButtonPhase.UP:
                    txtStyle = skin.upTxtStyle;
                    break;

                case WxButtonPhase.OVER:
                    txtStyle = skin.overTxtStyle;
                    break;

                case WxButtonPhase.DOWN:
                    txtStyle = skin.downTxtStyle;
                    break;

                case WxButtonPhase.DISABLED:
                    txtStyle = skin.disabledTxtStyle;
                    break;
            }

            return txtStyle;
        }

        private function get skin():IWxLabelButtonSkin
        {
            return _skin as IWxLabelButtonSkin;
        }
    }
}
